﻿// Lesson17.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <string_view>
#include "SpreadSheetCell.h"
#include "DoubleSpreadSheetCell.h"
#include "StringSpreadSheetCell.h"
#include <typeinfo>


class Product //A
{
public:
	std::string name;
};

class Cherry:public virtual Product
{
public:
	Cherry() = default;
	Cherry(double d)
	{
		std::cout << "cd:" << d << std::endl;
	}
	Cherry(std::string_view str)
	{
		std::cout << "sv:"<< str << std::endl;
	}

	virtual double size()
	{
		return 2.5;
	}

	virtual void polish()
	{
		std::cout << "void---" << std::endl;
	}
public:
	virtual double Price(int n=5)
	{
		double dPrice = n * PricePerKg() + PostFee(n);
		std::cout << "Normal Price=" << dPrice << std::endl;
		return dPrice;
	}
public:
	virtual double PricePerKg()
	{
		return 39.9;
	}
public:
	static double PostFee(int n)
	{
		return n * 8;
	}
public:
	int mIntC;

	static void test_func() 
	{
		std::cout << "base test_func" << std::endl;
	}
};



class Bing :public virtual Product
{
public:
	Bing() = default;
	Bing(double d)
	{
		std::cout << "double:" << d << std::endl;
	}
public:
	int mIntB;
};

class BingCherry : public Cherry,public Bing
{
public:

	using Cherry::Cherry;
	using Bing::Bing;
	BingCherry(double d)
		//:Cherry(d),Bing(d)
	{
		std::cout << "bcd:" << d << std::endl;
	}
	BingCherry(int nsize)
	{
		std::cout << "int:" << nsize << std::endl;
	}
	virtual double size() override
	{
		return 1.5;
	}
	using Cherry::polish;
	virtual void polish(const std::string& str)
	{
		std::cout << str<<std::endl;
	}

	double Price(int n = 3) override
	{
		double dPrice = n * PricePerKg() + PostFee(n);
		std::cout << "Bing Price="<< dPrice <<std::endl;
		return dPrice;
	}
protected:
	using Cherry::PricePerKg;
public:
	static void test_func()
	{
		std::cout << "sub test_func" << std::endl;
	}

};

class CherryTree
{
public:
	virtual Cherry* pick()
	{
		return new Cherry();
	}
public:
	int m_Height;
};


class BingCherryTree :public CherryTree
{
public:
	BingCherryTree() = default;
	BingCherryTree(const BingCherryTree& other)
		:CherryTree(other)
	{
	}

	BingCherryTree& operator = (const BingCherryTree& other)
	{
		if (&other == this)
		{
			return *this;
		}
		CherryTree::operator=(other);
		return *this;
	}

	virtual BingCherry* pick() override
	{
		return new BingCherry(2.0);
	}
};


void getTreeType(const CherryTree& pTree)
{
	const std::type_info& treeInfo = typeid(pTree);
	std::cout <<"raw name:"<< treeInfo.raw_name() << std::endl;
	std::cout << "name:" << treeInfo.name() << std::endl;
	if (typeid(pTree) == typeid(BingCherryTree))
	{
		std::cout << "BingCherryTree" << std::endl;
	}
	else
	{
		std::cout << "NormalCherryTree" << std::endl;
	}
	std::cout << "--------------------------------" << std::endl;
}



int main()
{
	
	//DoubleSpreadSheetCell dCell;

	//StringSpreadSheetCell sCell;

	//SpreadSheetCell* pDoubleCell = new DoubleSpreadSheetCell();

	//StringSpreadSheetCell* pCell = new StringSpreadSheetCell();

	//SpreadSheetCell baseCell;

	//DoubleSpreadSheetCell dCell;

	//baseCell = dCell;

	//StringSpreadSheetCell* pStringCell = 
	//	dynamic_cast<StringSpreadSheetCell*>(pCell);

	//dCell.SetValue("3.14");

	//pStringCell->SetValue(std::string_view("ABC"));
	//sCell.SetValue(std::string_view("ABC"));

	//std::cout << dCell.GetValue() << std::endl;
	//std::cout << sCell.GetValue() << std::endl;

	//delete pStringCell;

	//std::cout << pStringCell->GetValue() << std::endl;

	//BingCherryTree bct;

	//Cherry* pCherry = bct.pick();

	//std::cout << pCherry->size() << std::endl;

	//BingCherry cherry;

	//BingCherry cherry(2);

	//BingCherry cherrysv(std::string_view("2.12"));

	//BingCherry cherryd(1.85);

	//cherryd.polish();

	//Cherry::test_func();

	//Cherry myBase;

	//myBase.Price();

	//BingCherry myDerived(2.1);

	//myDerived.Price();

	//Cherry* pBingCherr = &myDerived;

	//std::cout<< pBingCherr->PricePerKg() <<std::endl;

	//BingCherryTree bct;

	//CherryTree ct;
	////bct.m_Height = 20;
	////BingCherryTree bct2;
	////bct2 = bct;
	////std::cout << bct2.m_Height << std::endl;

	//CherryTree* pBingCherryTree = new BingCherryTree();

	//getTreeType(bct);
	//getTreeType(ct);
	//getTreeType(*pBingCherryTree);

	BingCherry cherry(2);


	cherry.name = "cherry";

	void* pVoid = (void*)&cherry;

	Cherry* pCherr = (Cherry*)(pVoid);

	if (pVoid == pCherr)
	{
		std::cout << "same addr" << std::endl;
	}
	else
	{
		std::cout << "not same addr" << std::endl;
	}

	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
